package top.infopub.util;


import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.curator.framework.CuratorFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import top.infopub.zookeeper.lock.ZkLocker;


/**
 * ID生成器   分布式环境下唯一
 * @author Awoke
 * @version 2018年9月14日
 * @see IdFactory
 * @since
 */
public final class IdFactory {

    private static final Logger log = LoggerFactory.getLogger(IdFactory.class);

    private static char numbersAndLetters[] = null; // 随机数生成的字符范围

    private static CuratorFramework client;
    static {
        client = SpringContext.getBean(CuratorFramework.class);
    }

    private static final String LOCK_PRE_CODE = "idFactory";

    /**
     * 获取一个20位随机流水号，分布式环境下唯一 </br>
     * yyMMddHHmmssSSS + 5位随机数字
     * @return
     */
    public static String getRandomSerialNumber() {
        ZkLocker locker = new ZkLocker(client);
        try {
            // 休息1ms 保证SSS 唯一
            Thread.sleep(1);
            boolean flag = locker.lock(LOCK_PRE_CODE + "/yyMMddHHmmssSSS00000");
            if (flag) {
                String sequence = DateFormatUtils.format(new Date(), "yyMMddHHmmssSSS");
                return sequence + RandomStringUtils.randomNumeric(5);
            }
        }
        catch (Exception e) {
            log.error("", e);
        }
        finally {
            locker.unlock();
        }
        return null;
    }

    /**
     * 获取一个32位UUID 小写 不含-
     * @return
     */
    public static String getUUIDSerialNumber() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
    
    /**
     * 获取一个32位UUID 大写 不含-
     * @return
     */
    public static String getUUIDUpper() {
        return getUUIDSerialNumber().toUpperCase();
    }

    /**
     * 读取随机数字
     * @param i 取值个数
     * @return String
     */
    public static final String randomString(int i) {
        if (i < 1) {
            return null;
        }
        numbersAndLetters = "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
        char ac[] = new char[i];
        for (int j = 0; j < ac.length; j++ ) {
            ac[j] = numbersAndLetters[ThreadLocalRandom.current().nextInt(71)];
        }
        return new String(ac);
    }

    /**
     * 读取随机数字
     * @param i 取值个数
     * @return String
     */
    public static final String randomNum(int i) {
        if (i < 1) {
            return null;
        }
        numbersAndLetters = "0123456789".toCharArray();
        char ac[] = new char[i];
        for (int j = 0; j < ac.length; j++ ) {
            ac[j] = numbersAndLetters[ThreadLocalRandom.current().nextInt(9)];
        }
        return new String(ac);
    }

    public static void main(String[] args) {

    }

}
